package com.zzvcom.office.word.doc;

import cn.hutool.core.codec.Base64;
import com.zzvcom.office.word.doc.util.TableProccessUtils;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.docx4j.convert.in.xhtml.FormattingOption;
import org.docx4j.convert.in.xhtml.XHTMLImporter;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.AltChunkType;
import org.docx4j.wml.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.web.bind.annotation.*;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author yujikuan
 * @Classname GenWordController
 * @Description 生成word下载服务
 * @Date 2024/8/15 15:52
 */
@RestController
@Slf4j
@RequestMapping("/htmlword")
public class HtmlWordController {

    public static final BigInteger MIN_VALUE = BigInteger.valueOf(300);

    public static final BigDecimal per = BigDecimal.valueOf(0.7D);

    @PostConstruct
    public void init() {
        RFonts font = Context.getWmlObjectFactory().createRFonts();
        font.setEastAsia("宋体");
        font.setAscii("Times New Roman");
        font.setHint(STHint.EAST_ASIA);
        font.setCs("宋体");

        XHTMLImporterImpl.addFontMapping("Songti SC", font);
        XHTMLImporterImpl.addFontMapping("SimSun",font);
    }

    private String toXHTML(String html) {
        final Document document = Jsoup.parse(html);
        document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
        //https://github.com/plutext/docx4j/issues/79
        return document.html().replace("&nbsp;", "\u00A0");
    }

    public static void setHeadFileName(HttpServletResponse response, String fileName) {
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("setHeadFileName", e);
        }
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setContentType("application/octet-stream;charset=utf-8");
    }


    @PostMapping("download")
    public void download(HttpServletResponse response, @RequestBody HtmlDTO htmlDTO) throws Docx4JException {

        // 创建一个新的Word文档
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
        for (String s : htmlDTO.getHtmlList()) {
            s = Base64.decodeStr(s, StandardCharsets.UTF_8);
            // 将HTML内容导入文档
            donwloadHelper(wordMLPackage, s,htmlDTO.getBaseUri());
        }
        setHeadFileName(response, htmlDTO.getFileName());
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            wordMLPackage.save(outputStream);
        } catch (IOException ex) {
            log.error("download", ex);
        }
    }



    @PostMapping("download_alt")
    public void downloadAlt(HttpServletResponse response, @RequestBody HtmlDTO htmlDTO) throws Docx4JException {
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
        for (String s : htmlDTO.getHtmlList()) {

            wordMLPackage.getMainDocumentPart().addAltChunk(AltChunkType.Html, s.getBytes(StandardCharsets.UTF_8));
        }
        setHeadFileName(response, htmlDTO.getFileName());
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            wordMLPackage.save(outputStream);
        } catch (IOException ex) {
            log.error("download", ex);
        }
    }

    /**
     * post 提交表单html，返回docx
     *
     * @param response
     * @param fileName
     * @param content
     * @throws Docx4JException
     */
    @PostMapping("post_download")
    public void postDownload(HttpServletResponse response, @RequestParam("fileName") String fileName,
                             @RequestParam("content") List<String> content,
                             String baseUri) throws Docx4JException {
        //log.info("content={}",content);
        // 创建一个新的Word文档
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
        for (String s : content) {
            // 将HTML内容导入文档
            donwloadHelper(wordMLPackage, s,baseUri);
        }
        setHeadFileName(response, fileName);
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            wordMLPackage.save(outputStream);
        } catch (IOException ex) {
            log.error("download", ex);
        }

    }

    private void donwloadHelper(WordprocessingMLPackage wordMLPackage, String s,String baseUri) throws Docx4JException {
        String html = toXHTML(s);
        log.info("html={}",html);
        XHTMLImporter importer = new XHTMLImporterImpl(wordMLPackage);
        importer.setParagraphFormatting(FormattingOption.CLASS_PLUS_OTHER);
        //importer.setTableFormatting(FormattingOption.IGNORE_CLASS);

        List<Object> convertList = importer.convert(html, baseUri);
      for (Object o : convertList) {
            if (o instanceof Tbl table) {
                //自动修复，就无线计算大小暂定
                if(table.getTblPr().getTblLayout()==null){
                    CTTblLayoutType ctTblLayoutType = ObjectFactory.get().createCTTblLayoutType();
                    table.getTblPr().setTblLayout(ctTblLayoutType);
                }
                //全部设置成自动
                table.getTblPr().getTblLayout().setType(STTblLayoutType.AUTOFIT);
            }
        }
        wordMLPackage.getMainDocumentPart().getContent().addAll(convertList);
    }
}
